/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package za.co.pas.spaceandtime.model;

import java.util.LinkedList;
import java.util.List;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.Query;
import org.apache.log4j.Logger;
import za.co.pas.business.abstracts.AbstractDataModel;
import za.co.pas.business.message.StatusMessage;
import za.co.pas.business.message.StatusMessageObject;
import za.co.pas.spaceandtime.data.BedType;
import za.co.pas.spaceandtime.data.CostingType;
import za.co.pas.spaceandtime.data.RoomType;

/**
 *
 * @author alabuschagne
 */
public class ConfigDataModel extends AbstractDataModel
{
    private static Logger logger = Logger.getLogger(ConfigDataModel.class);
    private List<CostingType> costingTypes = new LinkedList<CostingType>();
    private List<RoomType> roomTypes = new LinkedList<RoomType>();
    private List<BedType> bedTypes = new LinkedList<BedType>();

    /**
     * @return the costingTypes
     */
    public List<CostingType> getCostingTypes(boolean force)
    {
        if ((force) || (costingTypes == null) || (costingTypes.isEmpty()))
        {
            costingTypes = getCostingTypesDB();
        }
        return costingTypes;
    }

    /**
     * @param costingTypes the costingTypes to set
     */
    public void setCostingTypes(List<CostingType> costingTypes)
    {
        this.costingTypes = costingTypes;
    }

    /**
     * @return the roomTypes
     */
    public List<RoomType> getRoomTypes(boolean force)
    {
        if ((force) || (roomTypes == null) || (roomTypes.isEmpty()))
        {
            roomTypes = getRoomTypesDB();
        }
        return roomTypes;
    }

    /**
     * @param roomTypes the roomTypes to set
     */
    public void setRoomTypes(List<RoomType> roomTypes)
    {
        this.roomTypes = roomTypes;
    }

    private List<RoomType> getRoomTypesDB()
    {
        try
        {
            firePropertyChange(new StatusMessage(StatusMessageObject.SMO_INFO, "Getting all room types", StatusMessageObject.SMO_TYPE_READ));
            Query q = em.createQuery("SELECT r FROM RoomType r");
            setConnectionOk(true);
            return (List<RoomType>) q.getResultList();
        }
        catch (NoResultException ex)
        {
            //This is not a error
            firePropertyChange(new StatusMessage(StatusMessageObject.SMO_WARN, "No results for room types", StatusMessageObject.SMO_TYPE_READ));
            logger.info(ex.getMessage());
        }
        catch (NonUniqueResultException ex)
        {
            firePropertyChange(new StatusMessage(StatusMessageObject.SMO_ERROR, "Reading error: " + ex.getMessage(), StatusMessageObject.SMO_TYPE_READ));
            logger.error(ex.getMessage(), ex);
        }
        catch (IllegalStateException ex)
        {
            firePropertyChange(new StatusMessage(StatusMessageObject.SMO_ERROR, "Reading error: " + ex.getMessage(), StatusMessageObject.SMO_TYPE_READ));
            logger.error(ex.getMessage(), ex);
        }
        catch (IllegalArgumentException ex)
        {
            firePropertyChange(new StatusMessage(StatusMessageObject.SMO_ERROR, "Reading error: " + ex.getMessage(), StatusMessageObject.SMO_TYPE_READ));
            logger.error(ex.getMessage(), ex);
        }
        return null;
    }

    public List<BedType> getBedTypes(boolean force)
    {
        if ((force) || (bedTypes == null) || (bedTypes.isEmpty()))
        {
            bedTypes = getBedTypesDB();
        }
        return bedTypes;
    }

    /**
     * @return the bedTypes
     */
    public List<BedType> getBedTypesDB()
    {
        try
        {
            firePropertyChange(new StatusMessage(StatusMessageObject.SMO_INFO, "Getting all bed types", StatusMessageObject.SMO_TYPE_READ));
            Query q = em.createQuery("SELECT r FROM BedType r");
            setConnectionOk(true);
            return (List<BedType>) q.getResultList();
        }
        catch (NoResultException ex)
        {
            //This is not a error
            firePropertyChange(new StatusMessage(StatusMessageObject.SMO_WARN, "No results for bed types", StatusMessageObject.SMO_TYPE_READ));
            logger.info(ex.getMessage());
        }
        catch (NonUniqueResultException ex)
        {
            firePropertyChange(new StatusMessage(StatusMessageObject.SMO_ERROR, "Reading error: " + ex.getMessage(), StatusMessageObject.SMO_TYPE_READ));
            logger.error(ex.getMessage(), ex);
        }
        catch (IllegalStateException ex)
        {
            firePropertyChange(new StatusMessage(StatusMessageObject.SMO_ERROR, "Reading error: " + ex.getMessage(), StatusMessageObject.SMO_TYPE_READ));
            logger.error(ex.getMessage(), ex);
        }
        catch (IllegalArgumentException ex)
        {
            firePropertyChange(new StatusMessage(StatusMessageObject.SMO_ERROR, "Reading error: " + ex.getMessage(), StatusMessageObject.SMO_TYPE_READ));
            logger.error(ex.getMessage(), ex);
        }
        return null;
    }

    /**
     * @param bedTypes the bedTypes to set
     */
    public void setBedTypes(List<BedType> bedTypes)
    {
        this.bedTypes = bedTypes;
    }

    private List<CostingType> getCostingTypesDB()
    {
         try
        {
            firePropertyChange(new StatusMessage(StatusMessageObject.SMO_INFO, "Getting all costing types", StatusMessageObject.SMO_TYPE_READ));
            Query q = em.createQuery("SELECT r FROM CostingType r");
            setConnectionOk(true);
            return (List<CostingType>) q.getResultList();
        }
        catch (NoResultException ex)
        {
            //This is not a error
            firePropertyChange(new StatusMessage(StatusMessageObject.SMO_WARN, "No results for costing types", StatusMessageObject.SMO_TYPE_READ));
            logger.info(ex.getMessage());
        }
        catch (NonUniqueResultException ex)
        {
            firePropertyChange(new StatusMessage(StatusMessageObject.SMO_ERROR, "Reading error: " + ex.getMessage(), StatusMessageObject.SMO_TYPE_READ));
            logger.error(ex.getMessage(), ex);
        }
        catch (IllegalStateException ex)
        {
            firePropertyChange(new StatusMessage(StatusMessageObject.SMO_ERROR, "Reading error: " + ex.getMessage(), StatusMessageObject.SMO_TYPE_READ));
            logger.error(ex.getMessage(), ex);
        }
        catch (IllegalArgumentException ex)
        {
            firePropertyChange(new StatusMessage(StatusMessageObject.SMO_ERROR, "Reading error: " + ex.getMessage(), StatusMessageObject.SMO_TYPE_READ));
            logger.error(ex.getMessage(), ex);
        }
        return null;
    }

    public void add(CostingType ct)
    {
        if(costingTypes == null)
        {
            costingTypes = new LinkedList<CostingType>();
        }
        costingTypes.add(ct);
    }

}
